home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 1 Issue 2
/
PDCD-1 - Issue 02.iso
/
_utilities
/
utilities
/
003
/
motorola
/
Sources
/
c
/
as
next >
Wrap
Text File
|
1993-07-18
|
15KB
|
413 lines
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* #include <kernel.h> */
#include "mselect.h" /*external selection of microprocessor symbol table*/
#include "proto.h"
#include "as.h"
#include "structs.h"
#include "glovars.h"
void stable(struct nlist * ptr);
void cross(struct nlist * point);
/*
* as --- cross assembler main program
*
* Note: Compile with define DEBUG for function module debug statements. Compile
* with define DEBUG2 for version 2 debug statements only. Compile with
* define IBM to use original, non- Amiga, non-MAC, non-UNIX fgets()
* function. Amiga version will accept IBM generated source code but not the
* other way around. Note added version (TER) 2.01 19 June 1989.
*/
int
main(int argc, char **argv)
{
char **np;
char *i;
int j = 0;
fprintf(stderr, "Assembler release TER_2.0 version 2.09 - (c) Motorola (free ware)\n");
fprintf(stderr, "Archimedes porting April 1993 Maurizio Ferrari - version 2.00\n");
if (argc < 2) {
fprintf(stderr, "Usage: %s [files] [-options]\n", argv[j]);
fprintf(stderr, "Example: %s FILE1.ASM FILE2.ASM -o <Obj_name> -x -list <List_name> -cyc -p50 -crlf -nnf\n", argv[j]);
exit(1);
}
Argv = argv;
while ((*argv[j] != '-') && (j < argc)) {
#ifdef DEBUG
printf("%s\n", argv[j]);
#endif
j++;
}
N_files = j - 1;
Lflag = 0;
Cflag = 0;
Sflag = 0;
CREflag = 0;
if (j < argc) {
while (j < argc) {
for (i = argv[j]; *i != 0; i++)
if ((*i <= 'Z') && (*i >= 'A'))
*i = *i + 32;
if (strcmp(argv[j], "-list") == 0) {
Lflag = 1;
} else if (strcmp(argv[j], "-cyc") == 0)
{Cflag = 1;}
else if (strcmp(argv[j], "-sym") == 0)
{Sflag = 1;}
else if (strcmp(argv[j], "-x") == 0)
{CREflag = 1;}
else if (strcmp(argv[j], "-crlf") == 0) /* test for crlf option */
{CRflag = 1;} /* add <CR><LF> to S record */
/* ver TER_1.1 June 3, 1989 */
else if (strcmp(argv[j], "-nnf") == 0) /* test for nnf option */
{nfFlag = 0;} /* nfFlag=1 means number
* INCLUDE separately. ver
* TER_2.0 6/17/89 */
else if (strcmp(argv[j], "-p") == 0) /* page every 50 lines */
{Pflag50 = 1;
PageLen = atoi(argv[++j]);} /* ver (TER) 2.01 19 Jun 89 */
else if (strcmp(argv[j], "-o") == 0) {
ObjFilePos = ++j;
} else if (*argv[j]) {
fprintf(stderr, "\nUnrecognized option '%s' on command line\n", argv[j]);
fprintf(stderr, "Valid options are:");
fprintf(stderr, " -list -cyc -sym -x -crlf -nnf -p <pages> -o <Obj name>\n\n");
exit(1);
}
j++;
}
}
if (ObjFilePos == 0)
fatal("\nmust specify output file");
/* errorInit(throwback,SourceFileName); */
fwdinit(); /* forward ref init */
initialize();
root = NULL;
Cfn = 0;
np = argv;
Line_num = 0; /* reset line number */
Local_Line_num = 0; /* reset line number */
while (++Cfn <= N_files)
if ((Fd = fopen(*++np, "r")) == NULL) {
fprintf(stderr, "as: can't open %s\n", *np);
} else {
errorInit(1, *np);
make_pass();
fclose(Fd);
errorFinish();
Local_Line_num = 0; /* reset line number */
}
if (Err_count == 0) {
Pass++;
re_init();
Cfn = 0;
np = argv;
Line_num = 0;
Local_Line_num = 0;
FdCount = 0; /* Resets INCLUDE file nesting ver TER_2.0
* 6/17/89 */
while (++Cfn <= N_files)
if ((Fd = fopen(*++np, "r")) != NULL) {
fprintf(stderr, "\nAssembling %s\n", *np);
errorInit(1, *np);
make_pass();
fclose(Fd);
errorFinish();
Local_Line_num = 0; /* reset Line_num for
* throwback */
}
fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
fprintf(stderr, "Error count = %d\n\n", Err_count); /* rel TER_2.0 */
if (Sflag == 1) {
fprintf(stderr, "Writing Symbols file\n");
stable(root);
fclose (Mapfil);
}
if (CREflag == 1) {
fprintf(stderr, "Writing Xref file\n");
cross(root);
fclose (Xfil);
}
if (CRflag == 1)
fprintf(Objfil, "S9030000FC%c\n", CR); /* ver TER_1.1 print w
* <CR> */
else
fprintf(Objfil, "S9030000FC\n"); /* at least give a
* decent ending */
fclose(Objfil); /* close file correctly ver TER_1.1 */
fclose(Listfil); /* close file */
} else { /* just note errors, TER_2.0 */
fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
fprintf(stderr, "Error count = %d\n\n", Err_count);
fclose(Listfil); /* close file */
}
fwd_done();
errorFinish();
exit(Err_count); /* neat for UNIX cuz can test return value in
* script but on other systems like Amiga,
* mostly just makes further script
* statements fail if >10, else nothing.
* Therefore, printed out byte count and
* error level. ver (TER) 2.02 19 Jun 89 */
}
void
initialize(void)
{
char c;
char *leafname, *maproot, *xroot, *lroot;/*input file leaf and output names*/
int i = 0;
#ifdef DEBUG
printf("Initializing\n");
#endif
Err_count = 0;
Pc = 0;
Pass = 1;
Ctotal = 0;
N_page = 0;
Line[MAXBUF - 1] = NEWLINE;
if (strlen(Argv[ObjFilePos]) > FILENAME_MAX)
fatal("obj_file name too long ");
Obj_name = (char *) malloc(strlen(Argv[ObjFilePos]));
lroot = (char *) malloc(strlen(Argv[1]));
maproot = (char *) malloc(strlen(Argv[1]));
xroot = (char *) malloc(strlen(Argv[1]));
if (Obj_name == NULL)
fatal("Cannot allocate space for obj name");
if (lroot == NULL)
fatal("Cannot allocate space for list file name");
if (maproot == NULL)
fatal("Cannot allocate space for map file name");
if (xroot == NULL)
fatal("Cannot allocate space for xref file name");
#ifdef DEBUG
printf("%d, %d\n", strlen(Argv[ObjFilePos]), sizeof(char));
printf("Oun =%s-\n", Obj_name);
#endif
do { /* copy -o <file name> into Obj_name */
c = Obj_name[i] = Argv[ObjFilePos][i];
i++;
} while (c && (i < FILENAME_MAX));
#ifdef DEBUG
printf("Fwd =%s\n", Fwd_name);
printf("Obj =%s\n", Obj_name);
#endif
Obj_name[--i] = EOS;
printf ("S19 Obj file: %s\n", Obj_name);
if ((Objfil = fopen(Obj_name, "w")) == NULL) {
fatal("Can't create object file");
}
leafname = strrchr (Argv[1], '.');
if (leafname == NULL)
{fatal ("cannot decipher leafname: empty ?");}
i=strlen(Argv[1]);
do {
i--;
} while (Argv[1][i-1] != '.');
do {
i--;
} while (Argv[1][i-1] != '.');
if (Lflag)
{ strncpy(lroot, Argv[1], i-1);
lroot[i-1] = EOS;
lroot=strcat(lroot, ".l");
lroot=strcat(lroot, leafname);
printf ("Listing file: %s\n", lroot);
if ((Listfil = fopen(lroot, "w")) == NULL) {
fatal("Panic! Can't create listing file");
}
}
if (Sflag)
{ strncpy(maproot, Argv[1], i-1);
maproot[i-1] = EOS;
maproot=strcat(maproot, ".m");
maproot=strcat(maproot, leafname);
printf ("Symbols file: %s\n", maproot);
if ((Mapfil = fopen(maproot, "w")) == NULL) {
fatal("Panic! Can't create symbols map file. Does 'm' dir exist?");
}
}
if (CREflag)
{ strncpy(xroot, Argv[1], i-1);
xroot[i-1] = EOS;
xroot=strcat(xroot, ".x");
xroot=strcat(xroot, leafname);
printf ("Xref file : %s\n", xroot);
if ((Xfil = fopen(xroot, "w")) == NULL) {
fatal("Panic! Can't create xref file. Does 'x' dir exist?");
}
}
localinit(); /* target machine specific init. */
}
void
re_init(void)
{
#ifdef DEBUG
printf("Reinitializing\n");
#endif
Pc = 0;
E_total = 0;
P_total = 0;
Ctotal = 0;
N_page = 0;
fwdreinit();
}
void
make_pass(void)
{
/*
* #ifdef IBM char *fgets();
*//* the original line */
/* #else */
/* char *FGETS(); *//* use own FGETS which is rewrite of lib function */
/* such that it discards <CR> so can read code */
/* generated on IBM */
/* June 3, 1989 rev TER_1.1 */
/* #endif */
#ifdef DEBUG
printf("Pass %d\n", Pass);
#endif
while (FGETS(Line, MAXBUF - 1, Fd) != (char *) NULL) { /* changed to FGETS */
/* which does not pass on <CR> June 3, 1989 */
/* rev TER_1.1 */
Line_num++;
Local_Line_num++;
P_force = 0; /* No force unless bytes emitted */
N_page = 0;
if (parse_line())
process();
if (Pass == 2 && Lflag && !N_page)
print_line();
P_total = 0; /* reset byte count */
Cycles = 0; /* and per instruction cycle count */
}
f_record();
}
/*
* parse_line --- split input line into label, op and operand
*/
int
parse_line(void)
{
register char *ptrfrm = Line;
register char *ptrto = Label;
/* char *skip_white(); */
if (*ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';')
/* added check for ';' ver TER_1.1 */
/* June 3, 1989 */
return (0); /* a comment line */
while (delim(*ptrfrm) == NO) /* parsing Label */
*ptrto++ = *ptrfrm++;
if (*--ptrto != ':')
ptrto++; /* allow trailing : */
*ptrto = EOS;
ptrfrm = skip_white(ptrfrm);
if (*ptrfrm == ';') { /* intercept comment after label, ver TER_2.0 */
*Op = *Operand = EOS; /* comment, no Opcode or Operand */
return (1);
}
ptrto = Op;
while (delim(*ptrfrm) == NO) /* parsing Opcode */
*ptrto++ = mapdn(*ptrfrm++);
*ptrto = EOS;
ptrfrm = skip_white(ptrfrm);
if (*ptrfrm == ';') { /* intercept comment, ver TER_2.0 */
*Operand = EOS; /* comment, no Operand */
return (1);
}
ptrto = Operand;
while ((*ptrfrm != NEWLINE) && ((*ptrfrm != ';')||(*Op != 'fcc'))) /* ver TER_2.0 */
*ptrto++ = *ptrfrm++; /* kill comments */ /* buggy: if FCC ';'
* error reported
* removed 27/6/93 */
*ptrto = EOS;
#ifdef DEBUG
printf("Label-%s-\n", Label);
printf("Op----%s-\n", Op);
printf("Operand-%s-\n", Operand);
#endif
return (1);
}
/*
* process --- determine mnemonic class and act on it
*/
void
process(void)
{
register struct oper *i;
/* struct oper *mne_look(); */
Old_pc = Pc; /* setup `old' program counter */
Optr = Operand; /* point to beginning of operand field */
if (*Op == EOS) { /* no mnemonic */
if (*Label != EOS)
install(Label, Pc);
} else if ((i = mne_look(Op)) == NULL)
error("Unrecognized Mnemonic");
else if (i->class == PSEUDO)
do_pseudo(i->opcode);
else {
if (*Label)
install(Label, Pc);
if (Cflag)
Cycles = i->cycles;
do_op(i->opcode, i->class);
if (Cflag)
Ctotal += Cycles;
}
}
#ifndef IBM
char *
FGETS(char *s, int n, register FILE * iop)
{ /* get at most n chars from iop */
/* Added rev TER_1.1 June 3, 1989 */
/* Adapted from Kernighan & Ritchie */
/*
* An fgets() that is IBM proof. Not needed if this IS an IBM
*/
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(iop)) != EOF) { /* read chars if not
* file end */
if ((*cs = c) != CR)
cs++; /* incr buffer pointer if not CR */
/* If CR, leave to be written over */
if (c == '\n')
break;
}
*cs = '\0'; /* replace NEWLINE with NULL as in standard
* fgets() */
return ((c == EOF && cs == s) ? NULL : s); /* return NULL if this
* is EOF */
}
#endif